<?php
session_start();
class AdminRenderer extends Renderer
{
	/**
	 * 
	 * Enter description here ...
	 * @var unknown_type
	 */
	private $readOnlyFields = array('save', 'nefub_id', 'nefub_name', 'update_time', 'game_nefub_id', 'season_nefub_id');
	
	/**
	 * 
	 * Enter description here ...
	 * @var unknown_type
	 */
	private $hideFields = array('id', 'season_id');
	
	/**
	 * 
	 * Enter description here ...
	 * @var unknown_type
	 */
	private $updates = array();
	 
	/**
	 * 
	 * Enter description here ...
	 * @var string
	 */
	private $mode; 
	 
	/**
	 * 
	 * Enter description here ...
	 * @var int
	 */
	private $editId; 
	
	/**
	 * 
	 * 
	 * Enter description here ...
	 * @var array
	 */
	protected $arguments;
	
	public function __construct(array $arguments)
	{
		parent::__construct();
		$this->arguments = $arguments;
		$this->subject = $arguments[1];
		$this->mode = $arguments[2];
		$this->editId = $arguments[3];
		
		$this->templateBaseDir = '/beheer';
		$this->assign('loggedIn', Account::getLoggedIn());
	}
	
	public function run()
	{
		if(!Account::getLoggedIn() && $this->subject != 'inloggen')
		{
			$this->redirect('/beheer/inloggen');
		}
		$this->assign('subject', $this->subject);
		switch ($this->subject)
		{			
			case 'geslacht':
				$this->showGenders();
				break;
			case 'poule':
				$this->showPoules();
				break;
			case 'wedstrijd':
				$this->showGames();
				break;
			case 'team':
				$this->showTeams();
				break;
			case 'persoon':
				$this->showPersons();
				break;
			case 'speler':
				$this->showTeamPersons();
				break;
			case 'speler':
				$this->showTeamPersons();
				break;
			case 'locatie':
				$this->showLocations();
				break;
			case 'club':
				$this->showClubs();
				break;
			case 'competitie':
				$this->showCompetitions();
				break;
			case 'wedstrijdspeler':
				$this->showGamePersons();
				break;
			case 'wedstrijdactie':
				$this->showGameActions();
				break;
			case 'actietype':
				$this->showGameActionTypes();
				break;
			case 'wedstrijdleidingtype':
				$this->showRefereeTypes();
				break;
			case 'spelertype':
				$this->showGamePersonSpecialTypes();
				break;
			case 'instelling':				
				$this->showSettings();
				break;			
			case 'retrievelog':				
				$this->showRetrieveLogs();
				break;
			case 'log':				
				$this->showLog();
				break;
			case 'feedback':				
				$this->showFeedback();
				break;
			case 'inloggen':
				if(Account::getLoggedIn())
				{
					$this->redirect('/beheer/dashboard');
				}
				$this->showLogin();
				break;
			case 'uitloggen':
				$this->logout();
				break;
			case 'dashboard':
				$this->showDashboard();
				break;
			case 'cache':
				$this->showRenderCache();
				break;
			default:
				if(Account::getLoggedIn())
				{
					$this->redirect('/beheer/dashboard');
				}
				else
				{
					$this->redirect('/beheer/inloggen');
				}
			case 'vernieuwcache':
				$retriever = APIRetriever::getInstance();
				$retriever->clear_renders();
				break;
			break;
		}
	}	
	
	protected function showLogin()
	{
		if($_POST['submitLogin'])
		{
			$errors = array();
			
			if(empty($_POST['username']))
			{
				$error = true;
				$errors[] = 'Gebruikersnaam is niet ingevuld';
			}
			
			if(empty($_POST['password']))
			{
				$error = true;
				$errors[] = 'Wachtwoord is niet ingevuld';
			}
			
			$username = $_POST['username'];
			if(!$error)
			{
				$password = $_POST['password'];
				
				if($oAccount = Account::login($username, $password))
				{
					$this->redirect('/beheer/dashboard');
				}
				else 
				{
					$errors = 'Combinatie niet gevonden';
					$error = true;
				}
			}
			
			if($error)
			{
				$this->smarty->assign('errors', $errors);
				$this->smarty->assign('username', $username);
			}
		}
		
		$this->template = '/login.tpl';
		$this->showOutput();
	}
	
	protected function showDashboard()
	{
		
		$tables = Database::getTables();
		
		foreach($tables as $table)
		{
			$this->assign('count'.$table, Database::select_count($table));			
		}
		
		$lastLogs = RetrieveLog::getAll(null, 'id', 'desc', 1);
		$oLastLog = $lastLogs[0];
		
		$this->assign('oLastLog', $oLastLog);
		
		$this->template = '/dashboard.tpl';
		$this->showOutput();
	}
	
	protected function logout()
	{
		Account::logout();
		$this->redirect('/beheer/inloggen');
	}
	
	protected function showCompetitions()
	{
		switch($this->mode)
		{			
			case 'bewerken';			
				$oCompetition = new Competition($this->editId);
				$this->editObject($oCompetition);
				break;
			default:
				$this->showCompetitionDependentView('/competities.tpl');
				
		}
	}
	
	protected function showPoules()
	{
		switch($this->mode)
		{			
			case 'bewerken';			
				$oPoule = Poule::getByNefubId($this->editId);
				$this->editObject($oPoule);
				break;
			default:
				$this->assign('aPoules', Poule::getAll(array('competition_nefub_id'=> 0), 'name'));
				$this->showCompetitionDependentView('/poules.tpl');				
		}
	}
	
	protected function showGenders()
	{
		switch($this->mode)
		{			
			case 'bewerken';			
				$oGender = new Gender($this->editId);
				$this->editObject($oGender);
				break;
			default:
				$this->showCompetitionDependentView('/geslachten.tpl');
				
		}
	}
	
	protected function editObject(Model $oObject, $template = '')
	{			
		
				$form = new Form();
				if($_POST)
				{
					$this->save($oObject);
					$this->assign('updates', $this->updates);					
					$this->assign('errors', $form->getErrors());
				}
				
				$fields = $oObject->getTableStructure();
				
				$isSetting = false;
				if($oObject instanceof Setting)
				{
					$isSetting = true;
					$this->readOnlyFields[] = 'name';
					$this->readOnlyFields[] = 'info';
				}
				foreach($fields as $fieldName => $field)
				{
					
					if($isSetting && $fieldName == 'value')
					{
						$settingType = str_replace('BOOLEAN', 'tinyint(1)', $settingType);
						$settingType = str_replace('INTEGER', 'VARCHAR', $settingType);
						$settingType = str_replace('FLOAT', 'VARCHAR', $settingType);
						
						$field['Type'] = strtolower($settingType);						
					}
					
					if(!is_numeric($fieldName) && !in_array($fieldName, $this->hideFields))
					{
						$value = ($oObject->$fieldName);
						
						
						$fieldTable = convertDbFieldToTable($fieldName);

						if($fieldName != 'nefub_id' && substr($fieldName, -3, 3) == '_id')
						{
							
							// left join
							if(substr($fieldName, -9, 9) == '_nefub_id')
							{
								// left join on nefub_id
								$split = explode('_nefub_id', $fieldName);
								$valueField = 'nefub_id';
							}
							else 
							{
								// left join on id
								$split = explode('_id', $fieldName);
								$valueField = 'id';
							}
							
							
							$fieldTable = convertDbFieldToTable($fieldName);
																			
							if($fieldTable == 'Game')
							{
								$input = new GameDropdown($fieldName, $value, $oObject->getGame());
							}
							elseif($fieldTable == 'Team')
							{
								$input = new TeamDropdown($fieldName, $value);
							}
							elseif($fieldTable == 'Location')
							{
								$input = new LocationDropdown($fieldName, $value);
							}
							else
							{
								$input = new ModelDropdown($fieldName, $value, $fieldTable, $valueField);
							}
						}
						else if(substr(strtolower($field['Type']), 0, 4) == 'enum')
						{
							$input = new EnumDropdown($fieldName, $value, $field['Type']);
							
							if($isSetting)
							{
								$settingType = $value;
							}
						}
						else if($fieldName != 'nefub_id' && substr($field['Type'],0, 3) == 'int')
						{

							$length = (substr($field['Type'], 4, strlen($field['Type']) - 2));	
							if($length >= 5)
							{		
								$input = new InputText($fieldName, $value);
								$input->addValidator(new IntegerValidator(true, 0, pow(10, $length)));
							}
							else
							{
								$input = new NumericDropdown($fieldName, $value, 0, pow(10, $length) -1);								
							}
						}
						else if($fieldName == 'Period')
						{
							$values = array(1 => 1, 2 => 2, 3 => 3);					
							$input = new RadioButton($fieldName, $values, $value);
						}
						else if($field['Type'] == 'int(1)' || $field['Type'] == 'tinyint(1)')
						{							
							$input = new RadioBoolean($fieldName, $value);
						}
						else if($field['Type'] == 'time' && $oObject->getTable() != 'GameAction')
						{
							$input = new Dropdown($fieldName, $value);
							
							for ($i = 0; $i < 24; $i++)
							{
								$hour = $i;
								if($hour < 10)
								{
									$hour = '0'.$hour;
								}
								
								for ($j = 0; $j < 60; $j+= 10)
								{
									$minute = $j;
									if($minute < 10)
									{
										$minute = '0'.$minute;
									}
									$time = $hour . ':' . $minute;
									
									$input->addOption($time, $time. ':00');	
								}	
							}
						}
						elseif($field['Type'] == 'text')
						{
							$input = new TextArea($fieldName, $value);
						}
						else 
						{								
							$input = new InputText($fieldName, $value);	
						}

						// read-only fields
						if(in_array($fieldName, $this->readOnlyFields))
						{
							$input->setExtraAttribute('disabled', 'disabled');
						}
						
						if($field['Null'] == 'NO')
						{
							$input->addValidator(new Validator());
						}
						
						$form->addElement($input, $fieldName);
					}
				}
				$this->assign('form', $form);
				$this->assign('subject', $this->subject);
				$this->assign('backUrl', '/'.$this->subject);
				$this->assign('o'.get_class($oObject), $oObject);
				$this->showObjectView($oObject, $template);
		
	}
	
	protected function showPersons()
	{
		switch($this->mode)
		{			
			case 'bewerken';			
				$oPerson = Person::getByNefubId($this->editId);
				$this->editObject($oPerson);
				break;
			default:
				//$aPersons = Person::getAll(array(), 'name', 'asc');
				$aSortedPersons = Person::getSortedByAlphabet();	
				$this->assign('aSortedPersons', $aSortedPersons);
				$this->template = '/personen.tpl';
				$this->showOutput();
		}
	}
	
	protected function showTeamPersons()
	{
		switch($this->mode)
		{			
			case 'bewerken';			
				$oTeamPerson = new TeamPerson($this->editId);
				$this->editObject($oTeamPerson);
				break;
			default:
				$aTeamPersons = TeamPerson::getAll(array(), 'id', 'asc');
				$this->assign('aTeamPersons', $aTeamPersons);
				$this->template = '/personen.tpl';
				$this->showOutput();
		}
	}
	
	protected function showTeams()	
	{
		switch($this->mode)
		{			
			case 'bewerken';			
				$oTeam = Team::getByNefubId($this->editId);
				$this->editObject($oTeam);
				break;
			default:
				$this->showCompetitionDependentView('/teams.tpl');
		}
	}
	
	protected function showGames()	
	{
		switch($this->mode)
		{			
			case 'bewerken';			
				$oGame = Game::getByNefubId($this->editId);
				
				$this->editObject($oGame);
				break;
			case 'competitie':
				$oCompetition = Competition::getByNefubId($this->editId);
				$this->assign('oCompetition', $oCompetition);
				$this->template = '/competitie.wedstrijden.tpl';
				$this->showOutput();
			break;
			default:
				$this->showCompetitionDependentView('/competities.wedstrijden.tpl');
		}
	}
	protected function showLocations()	
	{
		switch($this->mode)
		{			
			case 'bewerken':				
				$oLocation = Location::getByNefubId($this->editId);				
				$this->editObject($oLocation, '/bewerken.tpl');
				break;			
			default:
				$query = 'SELECT DISTINCT(`city`)
								FROM `Location`
								ORDER BY `city` ASC';
				$cityRows = Database::select_rows_by_query($query);
				$cities = array();
				
				foreach($cityRows as $cityRow)
				{
					$name = $cityRow['city'];
					
					if(!is_array($cities[$name]))
					{
						$cities[$name] = array();
					}
					
					$cities[$name] = Location::getAll(array('city' => $name), 'name');
				}
				
				$this->assign('cities', $cities);
				$this->template = '/locaties.tpl';
				$this->showOutput();
				
		}
	}

	protected function showClubs()
	{
		switch($this->mode)
		{			
			case 'bewerken';			
				$oClub = Club::getByNefubId($this->editId);
				$this->editObject($oClub);
				break;
			default:
				$aClubs = Club::getAll(array(), 'name');
				$this->assign('aClubs', $aClubs);
				$this->template = '/clubs.tpl';
				$this->showOutput();
		}
	}
	
	// Join tables

	protected function showGamePersons()
	{
		switch($this->mode)
		{			
			case 'bewerken';			
				$oGamePerson = new GamePerson($this->editId);
				$this->editObject($oGamePerson);
				break;
			default:
				$aGamePersons = GamePerson::getAll(array(), 'id', 'asc');
				$this->assign('aGamePersons', $aGamePersons);
				$this->template = '/personen.tpl';
				$this->showOutput();
		}
	}
	
	protected function showGamePersonSpecialTypes()
	{
		$this->assign('title', 'Spelertypes');
		switch($this->mode)
		{			
			case 'bewerken';			
				$oGamePerson = new GamePersonSpecialType($this->editId);
				$this->editObject($oGamePerson);
				break;
			default:
				$aGamePersons = GamePersonSpecialType::getAll(array(), 'name', 'asc');
				$this->assign('aTypes', $aGamePersons);
				$this->template = '/types.tpl';
				$this->showOutput();
		}
	}
	
	protected function showGameActionTypes()
	{
		$this->assign('title', 'Wedstrijdactietypes');
		switch($this->mode)
		{			
			case 'bewerken';			
				$oType = new GameActionType($this->editId);
				$this->editObject($oType);
				break;
			default:
				$aGamePersons = GameActionType::getAll(array(), 'name', 'asc');
				$this->assign('aTypes', $aGamePersons);				
				$this->template = '/types.tpl';
				$this->showOutput();
		}
	}
	
	protected function showRefereeTypes()
	{
		$this->assign('title', 'Wedstrijdactietypes');
		switch($this->mode)
		{			
			case 'bewerken';			
				$oType = new RefereeType($this->editId);
				$this->editObject($oType);
				break;
			default:
				$aGamePersons = RefereeType::getAll(array(), 'name', 'asc');
				$this->assign('aTypes', $aGamePersons);				
				$this->template = '/types.tpl';
				$this->showOutput();
		}
	}
	
	protected function showGameActions()
	{
		switch($this->mode)
		{			
			case 'bewerken';	
				$oGameAction = new GameAction($this->editId);
				$this->assign('backUrl', '/beheer/wedstrijd/bewerken/'.$oGameAction->game_nefub_id);
				$this->editObject($oGameAction);
				break;
			default:
				$this->redirect();
		}
	}
	
	protected function showSettings()
	{
		switch($this->mode)
		{			
			case 'bewerken';	
				$oSetting = new Setting($this->editId);
				
				//$this->assign('backUrl', '/beheer/instellingen/');
				$this->editObject($oSetting);
				break;
			default:
				$aSettingCategories = SettingCategory::getAll(null, 'id');
				
				$aSettings = Setting::getAll(array('setting_category_id' => 0));
				$this->assign('aSettingCategories', $aSettingCategories);
				$this->assign('aSettings', $aSettings);
				$this->template = '/instellingen.tpl';
				$this->showOutput();
		}
	}
	
	protected function showRetrieveLogs()
	{
		switch($this->mode)
		{			
			case 'bewerken';	
				$oRetrieveLog = new RetrieveLog($this->editId);
				
				//$this->assign('backUrl', '/beheer/instellingen/');
				$this->editObject($oRetrieveLog);
				break;
			default:				
				$aRetrieveLogs = RetrieveLog::getAll(array(), 'start_time', 'desc');			
				$this->assign('aRetrieveLogs', $aRetrieveLogs);
				$this->template = '/retrievelogs.tpl';
				$this->showOutput();
		}
	}
	
	protected function showLog()
	{
		$filename = 'activelog.txt';
		if(!file_exists($filename))
		{
			$aLog = array();
		}
		else
		{
			$f = fopen($filename, 'r+');
			$data = fread($f, filesize($filename));
			$data = htmlentities($data);
			$aLog = explode("\n", $data);	
			rsort($aLog);
				
		}
		$this->assign('aLog', $aLog);
		$this->template = '/log.tpl';
		$this->showOutput();	
	}
	
	protected function showRenderCache()
	{
		array_shift($this->arguments);
		array_shift($this->arguments);
		
		if(!count($this->arguments))
		{
			$this->arguments[0] = 'renders';	
		}		
		elseif($this->arguments[0] == 'delete')
		{
			array_shift($this->arguments);
			

			$deletepath = implode('/', $this->arguments);
			if(!is_dir($deletepath) && file_exists($deletepath))
			{
				unlink($deletepath);	
			}
			else
			{ 
				recursive_remove_directory($deletepath);
			}
			
			
			array_pop($this->arguments);
			$directory = implode('/', $this->arguments);
			$this->redirect('/beheer/cache/'.$directory);
		}
		
		
		$directory = implode('/', $this->arguments);
		
		$handle = opendir($directory);
		
		$directories  = array();
		$files = array();
		
		while (false !== ($item = readdir($handle)))
		{
			if($item[0] != '.')
			{				
				$path = $directory.'/'.$item;
				
				// if the new path is a directory
			
				if(is_dir($path)) 
				{
					$directories[] = $item;
				}
				else
				{
					$files[] = $item;
				}
			}
			
		}
		// close the directory
		closedir($handle);
		array_pop($this->arguments);
		$up = implode('/', $this->arguments);
		$this->assign('up', $up);
		$this->assign('parent', $directory);
		$this->assign('directories', $directories);
		$this->assign('files', $files);
		$this->assign('nocontents', (count($files)+count($directories) == 0));
		$this->template = '/cachedirectories.tpl';
		$this->showOutput();
	}
	
	protected function showFeedback()
	{
		switch($this->mode)
		{			
			case 'bewerken';	
				$oFeedback = new Feedback($this->editId);			
				$this->editObject($oFeedback);
				break;
			default:
				$aFeedback = Feedback::getAll(array(), 'post_time', 'desc');
				$this->assign('aFeedback', $aFeedback);
				$this->template = '/feedback.tpl';
				$this->showOutput();
		}
	}
	
	
	/**
	 * 
	 * Enter description here ...
	 * @param Model $oObject
	 */
	protected function showObjectView(Model $oObject, $template = '')
	{
		if($template)
		{
			$this->template = $template;
		}
		else
		{
			$this->template = '/'.$this->mode.'.tpl';
		}
		
		$this->assign('o'.get_class($oObject), $oObject);
		$this->showOutput();
		
	}
	
	/**
	 * 
	 * Enter description here ...
	 * @param string $template
	 */
	protected function showCompetitionDependentView($template = '/list.tpl')
	{
		$aCompetitions = Competition::getAll();
		$this->assign('aCompetitions', $aCompetitions);
		$this->template = $template;
		$this->showOutput();		
	}
	
	/**
	 * 
	 * Enter description here ...
	 * @param unknown_type $oObject
	 */
	protected function save(Model $oObject)
	{
		foreach($_POST as $field => $value)
		{
			$oldValue = $oObject->$field;
			if(!is_numeric($field) && !in_array($field, $this->readOnlyFields) && trim($oldValue) != trim($value))
			{
				$this->updates[$field] = array('old' => $oldValue,
										'new' => $value);
				$oObject->$field = $value;
			}
		}
		$oObject->save();
	}
}